import re
from ViewControler import *
from commanded.Config import Config
import subprocess
from logs.Log import Log
import os

log = Log()


class EventHandler:
    def __init__(self, winData):
        self.data = winData
        self.openDialog = OpenDialog()

    def Invoke(self, obj, eventType, objList=None):
        """
        调用指定类型事件\n
        :param obj: 事件先关联对象
        :param objList: 控件列表（如果需要更多控件配合使用时）
        :param eventType: 事件类型
        """
        log.TimeStar()
        value = eventType.value
        label = self.data.SRGLabel
        lableView = self.data.lableView
        # ------------------------------------------------------------------
        if value == 101:  # 更新下拉框选择数据
            if obj.currentText():
                self.data.SSelect = obj.currentText()
        # ------------------------------------------------------------------
        elif value == 102:  # 输入框回车展示历史路径
            log.Show("102:  # 输入框回车展示历史路径")
            # 弹出历史地址选择框
            pathDialog = SearchPathDialog()
            # 判断历史路径是否为空
            if self.data.histryPath:
                # 不为空则添加历史路径
                pathDialog.SetList(self.data.histryPath)
            # 展示历史路径窗口
            pathDialog.ShowDialog()
            # 获取窗口返回结果：确定->返回 1 ，取消-> 返回 0
            if pathDialog.dialog.result() == 1:
                # 获取用户选择的历史路径，判断是否为空
                if pathDialog.GetListItem():
                    # 同步窗口数据类数据以及输入框中地址
                    path = pathDialog.GetListItem()
                    if not self.SetDir(path):
                        self.ShowMessage("无效路径")
                        return
                    obj.setText(path)
        # ------------------------------------------------------------------
        elif value == 103:  # 路径输入框文本变更事件
            path = obj.text()
            if not self.SetDir(path):
                self.ShowMessage("无效路径")
                return
        # ------------------------------------------------------------------
        elif value == 104:  # 选择路径按钮点击事件
            log.Show("104:  # 选择路径按钮点击事件")
            # 展示文件夹路径选择框，并获取返回值
            path = self.openDialog.ShowDirectory()
            if '/' in path:
                path = path.replace('/', '\\')

            if not self.SetDir(path):
                self.ShowMessage("无效路径")
                return
            obj.setText(path)
        # ------------------------------------------------------------------
        elif value == 105:  # 仅数据查询事件
            searcher = self.data.searcher
            dirPath = self.data.SExclPath
            show_dataList = []
            dataTempList = []
            numberList = set()
            pattern1 = "-?\d+\,-?\d+\,-?\d+"
            # 获取基础表框内容数据解析后的结果
            taLines = self.data.STargetEdit.splitlines()
            taLines.pop(0)
            for taLine in taLines:
                rewardsStr = re.findall(pattern1, taLine)
                if len(rewardsStr) > 0:
                    for data in rewardsStr:  # 格式：'11,20177,20'
                        strList = data.strip().split(',')  # 通过逗号分割成单个reward内容列表 演示：['11', '20177', '20']
                        if strList[0] not in numberList:
                            numberList.add(strList[0])
                            # 读取单个EXCEL表格
                            searcher.DoCommand(strList[0])
                        # 获取对应类型的缓存
                        reReader = searcher.GetReader(dirPath, strList[0])
                        # 判断道具表的资源类型是否正确
                        if strList[0] == "10":
                            if not reReader.IsResource(strList[1]):
                                strList[0] = self.data.MarkT(strList[0])
                                self.data.colorKey = 1
                        if strList[0] == "11":
                            if reReader.IsResource(strList[1]):
                                strList[0] = self.data.MarkT(strList[0])
                                self.data.colorKey = 1
                        # 缓存不为空时，获取道具名称
                        if reReader:
                            itemName = reReader.GetName(strList[1])
                        else:
                            itemName = self.data.MarkT('None')
                            self.data.colorKey = 1
                        # 将道具名称拼接到原来字符串道具ID的后方
                        strList[1] = strList[1] + ',' + itemName
                        dataTempList.append(str(strList))
                else:
                    # 如果当前行存在异常数据，则标记为空
                    self.data.colorKey = 1
                    dataTempList.append(self.data.MarkT('None'))
                # 将整理好地行数据添加到展示数据列表中
                show_dataList.append(''.join(dataTempList))
                dataTempList.clear()
            # 通过换行符将列表中的数据进行合并
            taText = '<br />'.join(show_dataList)
            # 展示数据读取结果
            obj.setHtml(taText.replace("'", "").replace('"', ""))
            if self.data.colorKey == 0:  # 标志为0时，说明无差异
                lableView.ShowLable(label, "数据查询完成", 0)
            elif self.data.colorKey == 1:
                lableView.ShowLable(label, "存在异常数据，请检查列表", 1)
        # ------------------------------------------------------------------
        elif value == 106:  # 活动数据校验按钮点击事件
            self.data.reAllInfo.clear()
            self.data.taAllInfo.clear()
            self.data.reDiffInfo.clear()
            self.data.taDiffInfo.clear()
            self.data.colorKey = 0
            diffInfo = []
            diffIndex = None

            # 判断是否非文本比对，文本比对无需校验格式
            if not self.data.SStrRadioButton:
                # 先进行格式校验，校验不通过，则不往下执行
                checker = self.data.CheckDataText()
                if not checker:
                    return

            # 判断是否勾选了规划检查和文本比对
            if self.data.SDataRadioButton:
                diffIndex = self.data.CheckData()  # 进行规划检查
            elif self.data.SStrRadioButton:
                if not self.data.StrCheck():  # 进行文本比对
                    diffInfo.append('纯文本比对存在【差异】')
                else:
                    diffInfo.append('纯文本比对无差异内容')
            else:
                pass

            if self.data.colorKey == 0:  # 标志为0时，说明无差异
                lableView.ShowLable(label, "无差异", 0)
            elif self.data.colorKey == 1:
                lableView.ShowLable(label, "有差异 有差异 有差异", 1)

            reLines = self.data.SResourceEdit.splitlines()
            taLines = self.data.STargetEdit.splitlines()

            if diffIndex:
                # 遍历差异下标，标记差异内容
                for x in diffIndex:
                    index = x + 1
                    reLines[index] = self.data.MarkT(reLines[index])
                    taLines[index] = self.data.MarkT(taLines[index])

            # 清空 三个输入框中的数据
            objList[0].clear()
            objList[1].clear()
            obj.clear()

            # 设置规划输入框的内容
            objList[0].appendHtml('<br />'.join(reLines))
            # 设置基础表输入框的内容
            objList[1].appendHtml('<br />'.join(taLines))
            # 将差异化信息列表内容进行遍历且转换为字符串
            for x in range(len(self.data.taAllInfo)):
                self.data.taAllInfo[x] = str(self.data.taAllInfo[x])
            # 将差异化信息列表合并为完整字符串
            taText = '<br />'.join(self.data.taAllInfo)
            # 将差异化信息内容设置为差异化信息展示框的内容
            obj.setHtml(taText.replace("'", "").replace('"', ""))
            # 如果点选了主动弹出详情比对，则弹出该窗口
            if self.data.SGoDataCheckBox:
                self.data.ShowAllInfo(self.data.SStrRadioButton)
        # ------------------------------------------------------------------
        elif value == 107:  # 活动数据添加列按钮点击事件
            log.Show(107, 20)
        # ------------------------------------------------------------------
        elif value == 108:  # 无绑定响应事件
            ...
        # ------------------------------------------------------------------
        elif value == 109:  # 比对详情弹窗按钮点击事件
            self.data.ShowAllInfo(self.data.SStrRadioButton)
        # ------------------------------------------------------------------
        elif value == 110:  # 规划输入框 文本变更事件
            text = obj.toPlainText()
            if '\t' in text:
                text = text.replace('\t', ' ')
                obj.setPlainText(text)
        # ------------------------------------------------------------------
        elif value == 111:  # 基础表输入框 文本变更事件
            text = obj.toPlainText()
            text.strip()
            target_rewards = self.data.config.parametersConfigJson['target_rewards']
            myTa_Reward = "rewards"
            changeKey = False

            if not text:
                return

            if '\t' in text:
                changeKey = True
                text = text.replace('\t', ' ')

            for target_reward in target_rewards:
                if target_reward in text:
                    myTa_Reward = target_reward

            if not self.data.SStrRadioButton:
                if self.data.SCostsComboBox:
                    costsRewards = f'costs {myTa_Reward}'
                    if self.data.SCostsComboBox == "rewards costs":
                        costsRewards = f'{myTa_Reward} costs'

                    if myTa_Reward not in text:
                        if 'costs' not in text:
                            text = f'{costsRewards}\n{text}'
                        else:
                            text = text.replace('costs', costsRewards)
                        changeKey = True
                    else:
                        if 'costs' not in text:
                            text = text.replace(myTa_Reward, costsRewards)
                            changeKey = True
                else:
                    if myTa_Reward not in text:
                        text = f'{myTa_Reward}\n{text}'
                        changeKey = True

            if changeKey:
                textLines = text.splitlines()
                strList = [x.strip() for x in textLines if x.strip()]
                obj.setPlainText('\n'.join(strList))

        # ------------------------------------------------------------------
        elif value == 201:  # 执行检查按钮点击事件
            log.Show(201, 20)
        # ------------------------------------------------------------------
        elif value == 301:  # 策略选择下拉框选择事件
            log.Show(301, 20)
        # ------------------------------------------------------------------
        elif value == 302:  # 添加策略按钮点击事件
            log.Show(302, 20)
        # ------------------------------------------------------------------
        elif value == 303:  # 策略检查执行按钮点击事件
            log.Show(303, 20)
        # ------------------------------------------------------------------
        elif value == 1:  # 默认设置点击事件
            settingDialog = SettingDialog()
            settingDialog.SetDatas(self.data)
            settingDialog.ShowDialog()
            # 获取窗口返回结果：确定->返回 1 ，取消-> 返回 0
            if settingDialog.dialog.result() == 1:
                configItems = settingDialog.GetConfigItems()
                isOK = self.data.config.SaveDefualtConfig(configItems)
                if isOK:
                    self.ShowMessage('默认配置设置成功,配置在下次打开时生效')
                else:
                    self.ShowMessage(self.data.config.eInfo)
        # ------------------------------------------------------------------
        elif value == 0:  # 无响应事件
            log.Show(0, 20)
        # ------------------------------------------------------------------
        elif value == 3:  # EXCEL读取设置点击事件
            text = obj.text()
            if text == 'openSetting':
                subprocess.Popen(['notepad.exe', self.data.config.readerConfigPath])
            elif text == 'reload':
                config = Config()
                isOK = config.SetDefault()
                if isOK:
                    self.data.searcher.ClearDic()
                    log.Show(self.data.searcher.dirDataDict)
                    self.data.config = config
                    self.data.SetSearcher()
                    lableView.ShowLable(label, "重载成功", 0)
                else:
                    self.openDialog.ShowMessage(''.join(config.eInfo))
                    lableView.ShowLable(label, "重载失败 重载失败 重载失败", 1)
                    os.startfile(self.data.config.readerConfigPath)
        # ------------------------------------------------------------------
        # ------------------------------------------------------------------
        # ------------------------------------------------------------------
        # ------------------------------------------------------------------
        # ------------------------------------------------------------------
        # ------------------------------------------------------------------
        # ------------------------------------------------------------------
        log.TimeEnd(eventType)

    def SetDir(self, path, ):
        """
        设置默认搜索路径\n
        :param path: 文件夹绝对路径
        :return: 设置成功返回True
        """

        if not path:
            return False

        if self.data.SExclPath == path:
            return True

        if os.path.exists(path):
            searcher = self.data.searcher
            dirPath = self.data.SExclPath = path

            # 判断新路劲是否存在于历史路径中，如果没有，则加入历史路径
            if path not in self.data.histryPath:
                self.data.histryPath.append(path)
                self.data.config.SaveHistoryPath(self.data.histryPath)

            if not searcher.HaveDir(dirPath):  # 判断路径是否 未 添加过
                searcher.AddDir(dirPath)  # 添加路径到搜索控制台
            else:
                searcher.SetDir(dirPath)
            return True
        else:
            return False

    def ShowMessage(self, text):
        """
        展示错误信心提示框\n
        :param text: 需要展示的信息内容
        """
        self.openDialog.ShowMessage(text)
